/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.uba.algo3.tp3.modelo.actores;

import fi.uba.algo3.tp3.modelo.servicios.ServicioJuego;
import fi.uba.algo3.tp3.modelo.inanimados.Obstaculo;
import java.util.Collection;
import java.util.LinkedList;

/**
 *
 * @author Familia
 */
public class FantasmaRapido extends Fantasma {

    public FantasmaRapido(ServicioJuego servicio, Integer distanciaDeColision) {
        super(servicio, distanciaDeColision);
    }

    public enum Movimientos{
        ARRIBA,ABAJO,IZQUIERDA,DERECHA;
    }
    
    private Collection<Movimientos> movimientos;

    private void espiarDireccionesPosibles(ServicioJuego servicio){
        this.movimientos = new LinkedList<Movimientos>();
        this.y += 1;
        Obstaculo obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo == null) {
            this.movimientos.add(Movimientos.ABAJO);
        }
        this.y -= 2;
        obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo == null) {
            this.movimientos.add(Movimientos.ARRIBA);
        }
        this.y += 1;
        this.x += 1;
        obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo == null) {
            this.movimientos.add(Movimientos.DERECHA);
        }
        this.x -= 2;
        obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo == null) {
            this.movimientos.add(Movimientos.IZQUIERDA);
        }
        this.x += 1;
    }

    public void moverIzquierda(){
        if(movimientos.contains(Movimientos.IZQUIERDA)){
           this.cambiarSentidoAHorizontalIzquierda();
        }else if(movimientos.contains(Movimientos.ABAJO)){
           this.cambiarSentidoAVerticalAbajo();
        }else if(movimientos.contains(Movimientos.ARRIBA)){
           this.cambiarSentidoAVerticalArriba();
        }else {
           this.cambiarSentidoAHorizontalDerecha();
        }
    }

    public void moverDerecha(){
        if(movimientos.contains(Movimientos.DERECHA)){
           this.cambiarSentidoAHorizontalDerecha();
        }else if(movimientos.contains(Movimientos.ABAJO)){
           this.cambiarSentidoAVerticalAbajo();
        }else if(movimientos.contains(Movimientos.ARRIBA)){
           this.cambiarSentidoAVerticalArriba();
        }else {
           this.cambiarSentidoAHorizontalIzquierda();
        }
    }

    public void moverArriba(){
        if(movimientos.contains(Movimientos.ARRIBA)){
           this.cambiarSentidoAVerticalArriba();
        }else if(movimientos.contains(Movimientos.DERECHA)){
           this.cambiarSentidoAHorizontalDerecha();
        }else if(movimientos.contains(Movimientos.IZQUIERDA)){
           this.cambiarSentidoAHorizontalIzquierda();
        }else {
           this.cambiarSentidoAVerticalAbajo();
        }
    }

    public void moverAbajo(){
        if(movimientos.contains(Movimientos.ABAJO)){
           this.cambiarSentidoAVerticalAbajo();
        }else if(movimientos.contains(Movimientos.DERECHA)){
           this.cambiarSentidoAHorizontalDerecha();
        }else if(movimientos.contains(Movimientos.IZQUIERDA)){
           this.cambiarSentidoAHorizontalIzquierda();
        }else {
           this.cambiarSentidoAVerticalArriba();
        }
    }

    //Primera aproximación a vivirAtacando y vivirHuyendo
    @Override
    protected void vivirAtacando(ServicioJuego servicio) {
        espiarDireccionesPosibles(servicio);
        Pacman pacman = servicio.getPacman();
        int distanciaHorizontal = this.getX() - pacman.getX();
        int distanciaVertical = this.getY() - pacman.getY();
        if (Math.abs(distanciaHorizontal) < Math.abs(distanciaVertical)) {
            if(distanciaHorizontal>0){
                moverIzquierda();
            }else if(distanciaHorizontal < 0) {
                moverDerecha();
            } else {
                moverArriba();
            }
        } else {
            if (distanciaVertical > 0) {
                moverArriba();
            } else if (distanciaVertical < 0){
                moverAbajo();
            } else {
                moverIzquierda();
            }
        }
        this.x += this.sentidoX;
        this.y += this.sentidoY;
//        Ya me fije que se pudiera mover
        Obstaculo obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo != null) {
            this.x -= this.sentidoX;
            this.y -= this.sentidoY;
        }
    }

    //Primera aproximación a vivirAtacando y vivirHuyendo
    @Override
    protected void vivirHuyendo(ServicioJuego servicio) {
        espiarDireccionesPosibles(servicio);
        Pacman pacman = servicio.getPacman();
        int distanciaHorizontal = this.getX() - pacman.getX();
        int distanciaVertical = this.getY() - pacman.getY();
        if (Math.abs(distanciaHorizontal) > Math.abs(distanciaVertical)) {
            if(distanciaHorizontal<0){
                moverIzquierda();
            }else if(distanciaHorizontal > 0) {
                moverDerecha();
            } else {
                moverArriba();
            }
        } else {
            if (distanciaVertical < 0) {
                moverArriba();
            } else if (distanciaVertical > 0){
                moverAbajo();
            } else {
                moverIzquierda();
            }
        }
        this.x += this.sentidoX;
        this.y += this.sentidoY;
//        Ya me fije que se pudiera mover
        Obstaculo obstaculo = servicio.obtenerObstaculoMasCercano(this, distanciaDeColision.doubleValue());
        if (obstaculo != null) {
            this.x -= this.sentidoX;
            this.y -= this.sentidoY;
        }
    }

    public void moverHorizontalmente(int distancia) {
        if (distancia > 0) {
            this.cambiarSentidoAHorizontalIzquierda();
        } else {
            this.cambiarSentidoAHorizontalDerecha();
        }
    }

    public void moverVerticalmente(int distancia) {
        if (distancia > 0) {
            this.cambiarSentidoAVerticalArriba();
        } else {
            this.cambiarSentidoAVerticalAbajo();
        }
    }

    @Override
    protected void vivirComido() {
        int distanciaHorizontal = this.getX() - posicionInicialX;
        int distanciaVertical = this.getY() - posicionInicialY;
        if (Math.abs(distanciaHorizontal) > Math.abs(distanciaVertical)) {
            moverHorizontalmente(distanciaHorizontal);
        } else {
            moverVerticalmente(distanciaVertical);
        }
        //cuando van a la jaula no importa si pasan por encima de los obstaculos
        this.x += sentidoX;
        this.y += sentidoY;
    }
}

